home *** CD-ROM | disk | FTP | other *** search
/ Developer Helper 1: Phil & Dave's Excellent CD / Excellent CD HFS.raw / Moof / Goodies / HyperCard Goodies / Serial Toolkit / Source Code / sendSPort.p < prev    next >
Text File  |  1988-11-18  |  4KB  |  161 lines

  1. (*
  2.     sendSPort string -- Send a string to the serial port driver, paying attention to the flags for
  3.         appending a linefeed after a carriage return, and for auto-wrapping the output.
  4.  
  5.     To compile and link this file using Macintosh Programmer's Workshop,
  6.  
  7.         pascal -w sendSPort.p
  8.         link -m ENTRYPOINT -o HyperCommands -rt XCMD=7033 -sn Main=sendSPort ∂
  9.             sendSPort.p.o "{MPW}"Libraries:interface.o
  10.  
  11.     © Copyright 1987,88 by Apple Computer, Inc.
  12.  
  13.     Initial coding 9/87 by Harry R. Chesley.
  14. *)
  15.  
  16. {$R-}
  17.  
  18. {$S sendSPort }     { Segment name must be the same as the command name. }
  19.  
  20. unit DummyUnit;
  21.  
  22. interface
  23.  
  24. uses MemTypes, QuickDraw, OSIntf, HyperXCmd;
  25.  
  26. procedure EntryPoint(paramPtr: XCmdPtr);
  27.     
  28. implementation
  29.  
  30. const
  31.  
  32. return = 13;                { Carriage return. }
  33. linefeed = 10;            { Line feed. }
  34. space = ord(' ');        { Space. }
  35.  
  36. type
  37.  
  38. Str31 = String[31];
  39.  
  40. procedure sendSPort(paramPtr: XCmdPtr); forward;
  41.  
  42. procedure EntryPoint(paramPtr: XCmdPtr);
  43.  
  44.     begin
  45.         sendSPort(paramPtr);
  46.     end;
  47.  
  48. procedure sendSPort(paramPtr: XCmdPtr);
  49.  
  50.     var io: ParmBlkPtr;
  51.         col: integer;
  52.  
  53.     {$I XCmdGlue.inc}
  54.  
  55.     procedure Fail(errMsg: Str255); { set theResult and quit }
  56.         begin
  57.             paramPtr^.returnValue := PasToZero(errMsg);
  58.             exit(sendSPort);
  59.         end;
  60.  
  61.     {$I SPortUtil.inc}
  62.  
  63.     function copyAndCount(copyFrom, copyTo: Ptr; var col: integer; doTheCopy: boolean): longInt;
  64.         { Copy and translate bytes from the source string to the destination, counting the size of the destination
  65.             as we go. If doTheCopy is not true, then don't actually do the copy, just accumulate the count. It assumes
  66.             that we're starting in the column indicated by col, and returns the new column in col. }
  67.  
  68.         var fromPtr, toPtr, nextFromPtr: Ptr;
  69.             nextCol: integer;
  70.             theChar: SignedByte;
  71.  
  72.         procedure copyOne(d: SignedByte);
  73.  
  74.             begin
  75.                 if doTheCopy then toPtr^ := d;
  76.                 toPtr := pointer(ord4(toPtr)+1);
  77.                 col := col+1;
  78.             end;
  79.  
  80.         procedure copyCRLF;
  81.  
  82.             begin
  83.                 copyOne(return);
  84.                 if ThisSPort.sendLFs then copyOne(linefeed);
  85.                 col := 1;
  86.             end;
  87.  
  88.         begin
  89.         { Cycle thru all the bytes to be copied. }
  90.         fromPtr := copyFrom; toPtr := copyTo;
  91.         while fromPtr^ <> 0 do
  92.             begin
  93.                 { Get the next byte. }
  94.                 theChar := fromPtr^;
  95.                 fromPtr := pointer(ord4(fromPtr)+1);
  96.                 { Check if it was a return. }
  97.                 if theChar = return then copyCRLF
  98.                 { Otherwise, check for auto-wrap on space. }
  99.                 else if ThisSPort.autoWrap and (theChar = space) and (col <= WRAPCOLUMN) then
  100.                     begin
  101.                         { Send the space. }
  102.                         copyOne(space);
  103.                         { This was a space, so we may want to auto-wrap here. Find out where the next auto-wrap
  104.                             would occur. }
  105.                         nextFromPtr := fromPtr;
  106.                         nextCol := col;
  107.                         while (nextFromPtr^ <> return) and (nextFromPtr^ <> space) and (nextFromPtr^ <> 0) do
  108.                             begin
  109.                                 nextFromPtr := pointer(ord4(nextFromPtr)+1);
  110.                                 nextCol := nextCol+1;
  111.                             end;
  112.                         { If the next auto-wrap is past the wrap column, then auto-wrap here. }
  113.                         if (nextCol > WRAPCOLUMN) and (fromPtr^ <> return) and (fromPtr^ <> 0) then copyCRLF;
  114.                     end
  115.                 { Otherwise, check for a forced auto-wrap (one word larger than a line). }
  116.                 else if ThisSPort.autoWrap and (col >= WRAPCOLUMN) then
  117.                     begin
  118.                         if col = WRAPCOLUMN then copyOne(space);
  119.                         copyCRLF;
  120.                         copyOne(theChar);
  121.                     end
  122.                 else copyOne(theChar);
  123.             end;
  124.  
  125.             { Compute the final size of the output. }
  126.             copyAndCount := ord4(toPtr) - ord4(copyTo);
  127.         end;
  128.  
  129.     begin
  130.         if paramPtr^.paramCount <> 1 then Fail('parameter count is not 1');
  131.  
  132.         SetUpSPortGlobals;
  133.         EnsureOpenPort;
  134.  
  135.         { Check for an empty string being sent. }
  136.         if paramPtr^.params[1] = nil then exit(sendSPort);
  137.         if paramPtr^.params[1]^^ = 0 then exit(sendSPort);
  138.  
  139.         { Get an I/O block. }
  140.         io := WaitForFreeIOBlk;
  141.  
  142.         { Get rid of the old buffer, if any. }
  143.         if io^.ioBuffer <> nil then DisposPtr(io^.ioBuffer);
  144.         { Figure out the size of the new buffer and allocate it. }
  145.         col := ThisSPort.currentColumn;
  146.         io^.ioBuffer := NewPtr(copyAndCount(paramPtr^.params[1]^,nil,col,false));
  147.         if io^.ioBuffer = nil then Fail('could not allocate buffer');
  148.  
  149.         { Copy the data into the buffer, and set the output request size. }
  150.         col := ThisSPort.currentColumn;
  151.         io^.ioReqCount := copyAndCount(paramPtr^.params[1]^,io^.ioBuffer,col,true);
  152.  
  153.         { Send the data to the port asynchronously. }
  154.         if PBWrite(io,true) <> noErr then Fail('PBWrite failed');
  155.  
  156.         { Remember the column. }
  157.         Globals^^.ports[Globals^^.selectedPort].currentColumn := col;
  158.     end;
  159.  
  160. end.
  161.